home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
176-200
/
disk_185
/
examples
/
pgtb
/
pgtb.zoo
/
tbsym.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-12-12
|
7KB
|
233 lines
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* |_o_o|\\ The Software Distillery */
/* |. o.| || Made available to the Amiga development community */
/* | . | || the authors: BBS: */
/* | o | || John Mainwaring (919)-471-6436 */
/* | . |// */
/* ====== */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* this routine reads the program and extracts symbol and debug information */
#include "tb.h"
#include "setjmp.h"
#define HUNK_UNIT 999
#define HUNK_NAME 1000
#define HUNK_CODE 1001
#define HUNK_DATA 1002
#define HUNK_BSS 1003
#define HUNK_RELOC32 1004
#define HUNK_RELOC16 1005
#define HUNK_RELOC8 1006
#define HUNK_EXT 1007
#define HUNK_SYMBOL 1008
#define HUNK_DEBUG 1009
#define HUNK_END 1010
#define HUNK_HEADER 1011
#define HUNK_OVERLAY 1013
#define HUNK_BREAK 1014
#define LINE (('L'<<24)|('I'<<16)|('N'<<8)|'E')
extern struct tbtemplate *tbdata;
extern jmp_buf bailout;
long hunkcount; /* used to match codefile hunks with PGTB file segments */
ULONG readhunk(FILE *);
void skipheaderhunk(FILE *);
void dosymbols(FILE *);
void dolines(FILE *);
int readsym(file)
FILE *file;
{
ULONG thishunk, lasthunk = 0;
if (setjmp(bailout))
/* get here if file utilities decide to abort quasi gracefully */
return(0);
hunkcount = -1; /* so first hunk will be 0 */
while (thishunk = readhunk(file))
lasthunk = thishunk;
return(lasthunk == HUNK_END);
}
ULONG readhunk(file)
FILE *file;
{
ULONG hunkid, size;
if (!(hunkid = forcegetlong(file)))
return(0); /* signal end of file (or confusion?) */
switch (hunkid) {
case HUNK_CODE: /* these hunks should match a segment but are */
case HUNK_DATA: /* otherwise of no interest */
hunkcount += 1; /* fall through to skip over hunk */
case HUNK_UNIT: /* these hunks have size and data which is of */
case HUNK_NAME: /* no interest to us */
skiplong(file, getlong(file));
break;
case HUNK_BSS: /* this hunk has only a size */
getlong(file);
hunkcount += 1; /* but it does create a segment */
break;
case HUNK_RELOC32: /* not interested in relocation info, which is */
case HUNK_RELOC16: /* size, reloc hunk num, and size longwords of */
case HUNK_RELOC8: /* info. Ends with size of 0. */
while (size = getlong(file))
skiplong(file, size + 1);
break;
case HUNK_EXT: /* should only be found in unlinked *.o files */
fprintf(stderr, "*** encountered HUNK_EXT: I give up\n");
return(0);
/* break; happens, but confuses compiler */
case HUNK_SYMBOL: /* Oh joy! my life is worthwhile */
dosymbols(file);
break;
case HUNK_DEBUG: /* My cup overflows */
dolines(file);
break;
case HUNK_END: /* end of a group of hunks - no info here */
break;
case HUNK_HEADER: /* some neat admin stuff we can skip over */
skipheaderhunk(file);
break;
case HUNK_OVERLAY: /* bunt on this for now... */
fprintf(stderr, "*** Overlays confuse me, I give up\n");
return(0);
/* break; happens, but confuses compiler */
case HUNK_BREAK: /* end of some overlays */
break;
default:
fprintf(stderr, "*** illegal hunkid %ld in program file\n", hunkid);
return(0); /* caller will give up now */
}
return(hunkid);
}
void skipheaderhunk(file)
/* --------------*/
FILE *file;
{
ULONG size, first, last;
long i;
/* do the names, which consist of a (possibly empty) list of */
/* {size, ASCII} terminated by a null size */
while (size = getlong(file))
skiplong(file, size);
getlong(file); /* table size - who needs it? */
first = getlong(file);
last = getlong(file);
if (tbdata->segcount != (last - first + 1))
{
fprintf(stderr, "*** code file hunk count does not match traceback\n");
longjmp(bailout, 1); /* abort */
}
for (i = 0; i < tbdata->segcount; i++)
{
if ((size = getlong(file)) != tbdata->segments[i].size >> 2)
{
fprintf(stderr, "*** segment %ld length $%lx != hunk length $%lx\n",
i, size, tbdata->segments[i].size >> 2);
longjmp(bailout, 1); /* abort */
}
}
}
void dosymbols(file)
/* ---------*/
FILE *file;
{
struct symbol_node *symaddr, *memaddr;
long memsize;
ULONG size;
while (size = getlong(file))
{
/* size includes extra word for null to terminate string */
memsize = sizeof(struct symbol_node) + size << 2;
if (!(memaddr = (struct symbol_node *)AllocMem(memsize, MEMF_CLEAR)))
{
fprintf(stderr, "*** memory allocation failed\n");
exit(FATAL);
}
memaddr->sn_memsize = memsize;
getblock(file, (ULONG *)&(memaddr->sn_sym[0]), size);
memaddr->sn_value = getlong(file) + tbdata->segments[hunkcount].addr;
symaddr = (struct symbol_node *)&(tbdata->segments[hunkcount].symbols);
while (symaddr->sn_next)
{
if (symaddr->sn_next->sn_value > memaddr->sn_value)
break;
else if (symaddr->sn_next->sn_value == memaddr->sn_value)
/* see if names match - don't discard aliases */
if (strcmp(symaddr->sn_next->sn_sym, memaddr->sn_sym) == 0)
/* we gots this one awready - chuck it */
{
FreeMem((char *)memaddr, memaddr->sn_memsize);
memaddr = 0;
}
/* else drop through - might match another alias */
symaddr = symaddr->sn_next;
}
if (memaddr) /* we didn't deallocate */
{
memaddr->sn_next = symaddr->sn_next;
symaddr->sn_next = memaddr;
}
}
}
void dolines(file)
/* -------*/
FILE *file;
{
/* fprintf(stderr, "found debug hunk\n"); */
ULONG size, memsize, htype;
char htypes[5];
struct line_node *memaddr, *lineaddr;
size = getlong(file);
memsize = (size << 2) + sizeof(struct line_node) - 16;
if ((memaddr = (struct line_node *)AllocMem(memsize, MEMF_CLEAR)) == 0)
{
fprintf(stderr, "*** unable to allocate line memory\n");
skiplong(file, size);
return;
}
memaddr->ln_size = memsize;
memaddr->ln_offset = getlong(file);
if ((htype = getlong(file)) != LINE)
{
longtoascii(htype, htypes);
fprintf(stderr, "*** unknown debug hunk type %lx = %s\n", htype, htypes);
skiplong(file, size-2);
FreeMem((char *)memaddr, memsize);
return;
}
getblock(file, (ULONG *)&memaddr->ln_nsize, size-2);
lineaddr = (struct line_node *)&(tbdata->segments[hunkcount].lines);
while (lineaddr->ln_next)
{
if (lineaddr->ln_next->ln_offset > memaddr->ln_offset)
break;
lineaddr = lineaddr->ln_next;
}
memaddr->ln_next = lineaddr->ln_next;
lineaddr->ln_next = memaddr;
/* for now just skip the debug hunk */
/* skiplong(file, getlong(file)); */
}